<!DOCTYPE html>






  


<html class="theme-next pisces use-motion" lang="zh-CN">
<head>
  <meta charset="UTF-8"/>
<meta http-equiv="X-UA-Compatible" content="IE=edge" />
<meta name="viewport" content="width=device-width, initial-scale=1, maximum-scale=2"/>
<meta name="theme-color" content="#222">












<meta http-equiv="Cache-Control" content="no-transform" />
<meta http-equiv="Cache-Control" content="no-siteapp" />






















<link href="/lib/font-awesome/css/font-awesome.min.css?v=4.6.2" rel="stylesheet" type="text/css" />

<link href="/css/main.css?v=6.2.0" rel="stylesheet" type="text/css" />


  <link rel="apple-touch-icon" sizes="180x180" href="/images/apple-touch-icon-next.png?v=6.2.0">


  <link rel="icon" type="image/png" sizes="32x32" href="/images/favicon-32x32-next.png?v=6.2.0">


  <link rel="icon" type="image/png" sizes="16x16" href="/images/favicon-16x16-next.png?v=6.2.0">


  <link rel="mask-icon" href="/images/logo.svg?v=6.2.0" color="#222">









<script type="text/javascript" id="hexo.configurations">
  var NexT = window.NexT || {};
  var CONFIG = {
    root: '/',
    scheme: 'Pisces',
    version: '6.2.0',
    sidebar: {"position":"left","display":"post","offset":12,"b2t":false,"scrollpercent":false,"onmobile":false},
    fancybox: false,
    fastclick: false,
    lazyload: false,
    tabs: true,
    motion: {"enable":true,"async":false,"transition":{"post_block":"fadeIn","post_header":"slideDownIn","post_body":"slideDownIn","coll_header":"slideLeftIn","sidebar":"slideUpIn"}},
    algolia: {
      applicationID: '',
      apiKey: '',
      indexName: '',
      hits: {"per_page":10},
      labels: {"input_placeholder":"Search for Posts","hits_empty":"We didn't find any results for the search: ${query}","hits_stats":"${hits} results found in ${time} ms"}
    }
  };
</script>


  




  <meta name="description" content="一、Android 6.0后的权限问题谷歌发布的Android 6.0,与之前的版本相比，有了很多的亮点。诸如App Permissions（软件权限管理）、Chrome Custom Tabs（Chrome的网页浏览体验提升）、App Links(APP关联)、Android Pay(安卓支付)、Fingerprint Support(指纹支持)、Power &amp;amp; Change(电量管理">
<meta name="keywords" content="Android,权限">
<meta property="og:type" content="article">
<meta property="og:title" content="Android 6.0(API 23)后的权限问题">
<meta property="og:url" content="http://blog.bisondev.cn/2017/05/08/Android6-0-API-23-后的权限问题/index.html">
<meta property="og:site_name" content="Bison分享日志">
<meta property="og:description" content="一、Android 6.0后的权限问题谷歌发布的Android 6.0,与之前的版本相比，有了很多的亮点。诸如App Permissions（软件权限管理）、Chrome Custom Tabs（Chrome的网页浏览体验提升）、App Links(APP关联)、Android Pay(安卓支付)、Fingerprint Support(指纹支持)、Power &amp;amp; Change(电量管理">
<meta property="og:locale" content="zh-CN">
<meta property="og:image" content="http://opl5tlfw9.bkt.clouddn.com/17-5-8/64581194-file_1494244715364_12fc2.png">
<meta property="og:updated_time" content="2017-05-08T15:41:21.503Z">
<meta name="twitter:card" content="summary">
<meta name="twitter:title" content="Android 6.0(API 23)后的权限问题">
<meta name="twitter:description" content="一、Android 6.0后的权限问题谷歌发布的Android 6.0,与之前的版本相比，有了很多的亮点。诸如App Permissions（软件权限管理）、Chrome Custom Tabs（Chrome的网页浏览体验提升）、App Links(APP关联)、Android Pay(安卓支付)、Fingerprint Support(指纹支持)、Power &amp;amp; Change(电量管理">
<meta name="twitter:image" content="http://opl5tlfw9.bkt.clouddn.com/17-5-8/64581194-file_1494244715364_12fc2.png">






  <link rel="canonical" href="http://blog.bisondev.cn/2017/05/08/Android6-0-API-23-后的权限问题/"/>



<script type="text/javascript" id="page.configurations">
  CONFIG.page = {
    sidebar: "",
  };
</script>

  <title>Android 6.0(API 23)后的权限问题 | Bison分享日志</title>
  









  <noscript>
  <style type="text/css">
    .use-motion .motion-element,
    .use-motion .brand,
    .use-motion .menu-item,
    .sidebar-inner,
    .use-motion .post-block,
    .use-motion .pagination,
    .use-motion .comments,
    .use-motion .post-header,
    .use-motion .post-body,
    .use-motion .collection-title { opacity: initial; }

    .use-motion .logo,
    .use-motion .site-title,
    .use-motion .site-subtitle {
      opacity: initial;
      top: initial;
    }

    .use-motion {
      .logo-line-before i { left: initial; }
      .logo-line-after i { right: initial; }
    }
  </style>
</noscript>

</head>

<body itemscope itemtype="http://schema.org/WebPage" lang="zh-CN">

  
  
    
  

  <div class="container sidebar-position-left page-post-detail">
    <div class="headband"></div>

    <header id="header" class="header" itemscope itemtype="http://schema.org/WPHeader">
      <div class="header-inner"><div class="site-brand-wrapper">
  <div class="site-meta ">
    

    <div class="custom-logo-site-title">
      <a href="/" class="brand" rel="start">
        <span class="logo-line-before"><i></i></span>
        <span class="site-title">Bison分享日志</span>
        <span class="logo-line-after"><i></i></span>
      </a>
    </div>
      
        <p class="site-subtitle">I'm not perfect,but I keep trying</p>
      
  </div>

  <div class="site-nav-toggle">
    <button aria-label="切换导航栏">
      <span class="btn-bar"></span>
      <span class="btn-bar"></span>
      <span class="btn-bar"></span>
    </button>
  </div>
</div>




<nav class="site-nav">
  
    <ul id="menu" class="menu">
      
        
        
        
          
          <li class="menu-item menu-item-home">
    <a href="/" rel="section">
      <i class="menu-item-icon fa fa-fw fa-home"></i> <br />首页</a>
  </li>
        
        
        
          
          <li class="menu-item menu-item-about">
    <a href="/about/" rel="section">
      <i class="menu-item-icon fa fa-fw fa-user"></i> <br />关于</a>
  </li>
        
        
        
          
          <li class="menu-item menu-item-tags">
    <a href="/tags/" rel="section">
      <i class="menu-item-icon fa fa-fw fa-tags"></i> <br />标签</a>
  </li>
        
        
        
          
          <li class="menu-item menu-item-categories">
    <a href="/categories/" rel="section">
      <i class="menu-item-icon fa fa-fw fa-th"></i> <br />分类</a>
  </li>
        
        
        
          
          <li class="menu-item menu-item-archives">
    <a href="/archives/" rel="section">
      <i class="menu-item-icon fa fa-fw fa-archive"></i> <br />归档</a>
  </li>
        
        
        
          
          <li class="menu-item menu-item-schedule">
    <a href="/schedule/" rel="section">
      <i class="menu-item-icon fa fa-fw fa-calendar"></i> <br />日程表</a>
  </li>
        
        
        
          
          <li class="menu-item menu-item-sitemap">
    <a href="/sitemap.xml" rel="section">
      <i class="menu-item-icon fa fa-fw fa-sitemap"></i> <br />站点地图</a>
  </li>

      
      
    </ul>
  

  

  
</nav>



  



</div>
    </header>

    


    <main id="main" class="main">
      <div class="main-inner">
        <div class="content-wrap">
          
            

          
          <div id="content" class="content">
            

  <div id="posts" class="posts-expand">
    

  

  
  
  

  

  <article class="post post-type-normal" itemscope itemtype="http://schema.org/Article">
  
  
  
  <div class="post-block">
    <link itemprop="mainEntityOfPage" href="http://blog.bisondev.cn/2017/05/08/Android6-0-API-23-后的权限问题/">

    <span hidden itemprop="author" itemscope itemtype="http://schema.org/Person">
      <meta itemprop="name" content="Bison Qin">
      <meta itemprop="description" content="">
      <meta itemprop="image" content="/images/avatar.gif">
    </span>

    <span hidden itemprop="publisher" itemscope itemtype="http://schema.org/Organization">
      <meta itemprop="name" content="Bison分享日志">
    </span>

    
      <header class="post-header">

        
        
          <h1 class="post-title" itemprop="name headline">Android 6.0(API 23)后的权限问题
              
            
          </h1>
        

        <div class="post-meta">
          <span class="post-time">

            
            
            

            
              <span class="post-meta-item-icon">
                <i class="fa fa-calendar-o"></i>
              </span>
              
                <span class="post-meta-item-text">发表于</span>
              

              
                
              

              <time title="创建时间：2017-05-08 17:30:08 / 修改时间：23:41:21" itemprop="dateCreated datePublished" datetime="2017-05-08T17:30:08+08:00">2017-05-08</time>
            

            
              

              
            
          </span>

          
            <span class="post-category" >
            
              <span class="post-meta-divider">|</span>
            
              <span class="post-meta-item-icon">
                <i class="fa fa-folder-o"></i>
              </span>
              
                <span class="post-meta-item-text">分类于</span>
              
              
                <span itemprop="about" itemscope itemtype="http://schema.org/Thing"><a href="/categories/Android/" itemprop="url" rel="index"><span itemprop="name">Android</span></a></span>

                
                
              
            </span>
          

          
            
          

          
          
             <span id="/2017/05/08/Android6-0-API-23-后的权限问题/" class="leancloud_visitors" data-flag-title="Android 6.0(API 23)后的权限问题">
               <span class="post-meta-divider">|</span>
               <span class="post-meta-item-icon">
                 <i class="fa fa-eye"></i>
               </span>
               
                 <span class="post-meta-item-text">阅读次数：</span>
               
                 <span class="leancloud-visitors-count"></span>
             </span>
          

          

          

          

        </div>
      </header>
    

    
    
    
    <div class="post-body" itemprop="articleBody">

      
      

      
        <h2 id="一、Android-6-0后的权限问题"><a href="#一、Android-6-0后的权限问题" class="headerlink" title="一、Android 6.0后的权限问题"></a>一、Android 6.0后的权限问题</h2><p>谷歌发布的Android 6.0,与之前的版本相比，有了很多的亮点。诸如App Permissions（软件权限管理）、Chrome Custom Tabs（Chrome的网页浏览体验提升）、App Links(APP关联)、Android Pay(安卓支付)、Fingerprint Support(指纹支持)、Power &amp; Change(电量管理 )等等。但是，我们今天要说的是App Permissions,没错，就是它。  </p>
<p>相信在Android 6.0之前，安卓开发者可以为所欲为地在App中获取用户的隐私资料，而且是在你不知情的情况下。这就引发了很多对隐私安全的争论，谷歌也知道了这个问题，本着用户至上的原则，在Android 6.0中，Android系统加入了软件管理权限。用户用起来是放心了很多，但对于开发者，说多都是泪，当然，只是要在编程的过程中做多一些工作而已。</p>
<p>在Android中，如果你在App中的AndroidManifest.xml中没有声明软件的权限，你的App就没权限去做相应的事，这是众所周知的。但是在Android 6.0后，有些权限即使你在AndroidManifest.xml文件中添加了声明，也还是会报java.lang.SecurityException异常。因为这个时候你很可能申请了Dangerous Permissions（危险权限），何为危险权限，下面会进行说明。</p>
<h2 id="二、权限的分类"><a href="#二、权限的分类" class="headerlink" title="二、权限的分类"></a>二、权限的分类</h2><p>按照谷歌API Guides的说法，系统权限分类几个保护</p>
<h3 id="1-Normal-permissions"><a href="#1-Normal-permissions" class="headerlink" title="1. Normal permissions"></a>1. Normal permissions</h3><p>从字面翻译过来就是普通权限，但是API Guides中的中文版中译成了正常权限，这翻译有点生硬了些，为了方便理解，以下称为普通权限。<br>引用官方对Normal permissions的解释：</p>
<blockquote>
<p>Normal permissions cover areas where your app needs to access data or resources outside the app’s sandbox, but where there’s very little risk to the user’s privacy or the operation of other apps. For example, permission to set the time zone is a normal permission. If an app declares that it needs a normal permission, the system automatically grants the permission to the app. For a full listing of the current normal permissions, see Normal permissions <a href="https://developer.android.com/guide/topics/permissions/normal-permissions.html" target="_blank" rel="noopener">Normal permissions</a>.</p>
</blockquote>
<p>也就是说，普通权限包括应用需要访问其沙盒（sandbox）外部数据或资源，也就是对用户隐私或其他应用操作风险很小的区域。例如，设置时区的权限就是普通权限，如果应用声明了其需要这些权限（其实也就是在AndroidManifest.xml中添加了声明），那么在使用中，系统会自动向应用授予该权限，并且用户无法撤销这些权限。<br><a id="more"></a><br>普通的权限有很多，以下为普通权限表：  </p>
<ul>
<li>ACCESS_LOCATION_EXTRA_COMMANDS              </li>
<li>ACCESS_NETWORK_STATE  </li>
<li>ACCESS_NOTIFICATION_POLICY  </li>
<li>ACCESS_WIFI_STATE  </li>
<li>BLUETOOTH  </li>
<li>BLUETOOTH_ADMIN  </li>
<li>BROADCAST_STICKY  </li>
<li>CHANGE_NETWORK_STATE  </li>
<li>CHANGE_WIFI_MULTICAST_STATE  </li>
<li>CHANGE_WIFI_STATE  </li>
<li>DISABLE_KEYGUARD  </li>
<li>EXPAND_STATUS_BAR  </li>
<li>GET_PACKAGE_SIZE  </li>
<li>INSTALL_SHORTCUT  </li>
<li>INTERNET  </li>
<li>KILL_BACKGROUND_PROCESSES  </li>
<li>MODIFY_AUDIO_SETTINGS  </li>
<li>NFC  </li>
<li>READ_SYNC_SETTINGS  </li>
<li>READ_SYNC_STATS  </li>
<li>RECEIVE_BOOT_COMPLETED  </li>
<li>REORDER_TASKS  </li>
<li>REQUEST_IGNORE_BATTERY_OPTIMIZATIONS  </li>
<li>REQUEST_INSTALL_PACKAGES  </li>
<li>SET_ALARM  </li>
<li>SET_TIME_ZONE  </li>
<li>SET_WALLPAPER  </li>
<li>SET_WALLPAPER_HINTS  </li>
<li>TRANSMIT_IR  </li>
<li>UNINSTALL_SHORTCUT  </li>
<li>USE_FINGERPRINT  </li>
<li>VIBRATE  </li>
<li>WAKE_LOCK  </li>
<li>WRITE_SYNC_SETTINGS  </li>
</ul>
<h3 id="2-Dangerous-permissions"><a href="#2-Dangerous-permissions" class="headerlink" title="2. Dangerous permissions"></a>2. Dangerous permissions</h3><blockquote>
<p>Dangerous permissions cover areas where the app wants data or resources that involve the user’s private information, or could potentially affect the user’s stored data or the operation of other apps. For example, the ability to read the user’s contacts is a dangerous permission. If an app declares that it needs a dangerous permission, the user has to explicitly grant the permission to the app.</p>
</blockquote>
<p>翻译过来也就是，危险权限包括应用需要涉及用户隐私信息的数据或资源，或者可能对用户存储的数据或其他应用的操作产生影响的区域。例如，读取用户的联系人的权限就属于危险权限。如果应用声明需要使用危险权限，就要那么用户就必须明确向该应用授予权限，否则应用就不能违背用户意愿去执行“危险操作”。</p>
<p>当然，危险权限的说法只在设备运行的是Android 6.0（API级别23）以上，并且应用的targetSdkVersion是23或更高的版本才有效。换句话说，如果你的设备是Android 6.0以下或者你使用的是targetSdkVersion在23以下的App，那么你的隐私将有可能被轻易的泄露。当然，Android 5.1（API级别22）或更低的版本，系统在安装时就会要求用户授予权限。</p>
<blockquote>
<p>If an app requests a dangerous permission listed in its manifest, and the app does not currently have any permissions in the permission group, the system shows a dialog box to the user describing the permission group that the app wants access to. The dialog box does not describe the specific permission within that group. For example, if an app requests the READ_CONTACTS permission, the system dialog box just says the app needs access to the device’s contacts. If the user grants approval, the system gives the app just the permission it requested.</p>
</blockquote>
<p>如果应用请求了AndroidManifest.xml列出的危险权限，而应用目前在权限组中没有任何权限，则系统会向用户显示一个对话框，描述应用要访问的权限组，对话框不描述组内的具体权限。例如，如果应用请求READ_CONTACTS 权限，系统对话框只是说明应用需要访问设备的联系信息。如果用户批准，系统将向应用授予其请求的权限。这一点我觉得我们国内的ROM厂商做的很好，在申请例如SEND_SMS 权限的时候，弹出的对话框提示的是该应用正在尝试发送短信。</p>
<p>如果应用请求其AndroidManifest.xml中列出的危险权限，而应用在同一权限组中已有另一项危险权限，则系统会立即授予该权限，无需与用户进行交互。例如，如果某应用已经请求并且被授予了 READ_CONTACTS 权限，然后它又请求 WRITE_CONTACTS，系统将立即授予该权限。</p>
<p>以下为危险权限和权限组<br> <img src="http://opl5tlfw9.bkt.clouddn.com/17-5-8/64581194-file_1494244715364_12fc2.png" alt=""></p>
<h3 id="3-Special-Permissions"><a href="#3-Special-Permissions" class="headerlink" title="3.Special Permissions"></a>3.Special Permissions</h3><p>顾名思义，就是特殊权限。例如SYSTEM_ALERT_WINDOW 和 WRITE_SETTINGS，这些权限的行为方式和普通权限和危险权限都不同，特别敏感。因此大多数应用都不应该使用这些特殊权限。如果应用实在是需要使用这些特殊权限时，必须先在AndroidManifest.xml文件中声明，然后发送用户授权的Intent，那么系统就会向用户显示详细的管理屏，以响应这些Intent</p>
<h2 id="三、动态申请权限"><a href="#三、动态申请权限" class="headerlink" title="三、动态申请权限"></a>三、动态申请权限</h2><h3 id="1-配置权限"><a href="#1-配置权限" class="headerlink" title="1. 配置权限"></a>1. 配置权限</h3><p>要使用权限，就要现在AndroidManifest.xml中先声明权限才行</p>
<pre><code>&lt;manifest xmlns:android=&quot;http://schemas.android.com/apk/res/android&quot;
    package=&quot;cn.bisondev.myframework&quot;&gt;

    &lt;application
        android:allowBackup=&quot;true&quot;
        android:icon=&quot;@mipmap/ic_launcher&quot;
        android:label=&quot;@string/app_name&quot;
        android:roundIcon=&quot;@mipmap/ic_launcher_round&quot;
        android:supportsRtl=&quot;true&quot;
        android:theme=&quot;@style/AppTheme&quot;&gt;
        &lt;activity android:name=&quot;.MainActivity&quot;&gt;
            &lt;intent-filter&gt;
                &lt;action android:name=&quot;android.intent.action.MAIN&quot; /&gt;

                &lt;category android:name=&quot;android.intent.category.LAUNCHER&quot; /&gt;
            &lt;/intent-filter&gt;
        &lt;/activity&gt;
    &lt;/application&gt;
&lt;/manifest&gt;
</code></pre><h3 id="2-判断系统版本"><a href="#2-判断系统版本" class="headerlink" title="2.判断系统版本"></a>2.判断系统版本</h3><pre><code>if(Build.VERSION.SDK_INT &gt;= Build.VERSION_CODES.M) //只有当系统是Android6.0以上时，才需要动态申请权限
</code></pre><h3 id="3-判断是否申请了权限"><a href="#3-判断是否申请了权限" class="headerlink" title="3.判断是否申请了权限"></a>3.判断是否申请了权限</h3><pre><code>int permissionStatus = ActivityCompat.checkSelfPermission(SMSActivity.this,Manifest.permission.SEND_SMS);
</code></pre><p>此时permissionStatus有两种取值  </p>
<ul>
<li>PackageManager.PERMISSION_GRANTED//已经授权给这个包了，接下来你可以执行你的业务逻辑代码</li>
<li>PackageManager.PERMISSION_DENIED//还没有授权给这个包，你要往下动态申请权限</li>
</ul>
<h3 id="4-判断是否可以通过弹窗解释授权"><a href="#4-判断是否可以通过弹窗解释授权" class="headerlink" title="4.判断是否可以通过弹窗解释授权"></a>4.判断是否可以通过弹窗解释授权</h3><pre><code>boolean hasPermission = ActivityCompat.shouldShowRequestPermissionRationale(SMSActivity.this,Manifest.permission.SEND_SMS);
</code></pre><p>当Build.VERSION.SDK_INT&gt;=23时，才有动态权限，才需要弹窗去申请，所以当Build.VERSION.SDK_INT &lt; 23时，返回的是false;这里可以从源码中看出来</p>
<pre><code>/*
 * @param activity The target activity.
 * @param permission A permission your app wants to request.
 * @return Whether you can show permission rationale UI.
 *
 * @see #checkSelfPermission(android.content.Context, String)
 * @see #requestPermissions(android.app.Activity, String[], int)
 */
public static boolean shouldShowRequestPermissionRationale(@NonNull Activity activity,
        @NonNull String permission) {
    if (Build.VERSION.SDK_INT &gt;= 23) {
        return ActivityCompatApi23.shouldShowRequestPermissionRationale(activity, permission);
    }
    return false;
}
</code></pre><p>这里可以看出，当你的Build.VERSION.SDK_INT小于23时，方法直接返回false,此时你可以直接请求申请任何需要的权限。如果用户以前拒绝了一个请求，那么这个方法将会是true。也就是说，用户第一次安装，这个方法返回的是false，只有当用户拒绝过，并且没有按不再提示该窗口之后，这个方法将会返回true。这个时候，可能用户不明白你是否需要这个权限，需要你对利用此权限进行解释说明。</p>
<h3 id="5-申请权限"><a href="#5-申请权限" class="headerlink" title="5.申请权限"></a>5.申请权限</h3><pre><code>ActivityCompat.requestPermissions(SMSActivity.this, permission,0);
</code></pre><h3 id="6-对申请权限结果进行处理"><a href="#6-对申请权限结果进行处理" class="headerlink" title="6.对申请权限结果进行处理"></a>6.对申请权限结果进行处理</h3><p>在onRequestPermissionsResult（）方法中，可以对申请结果进行相应的处理  </p>
<pre><code>/**
 * 处理申请权限的结果
 * @param requestCode
 * @param permissions
 * @param grantResults
 */
@Override
public void onRequestPermissionsResult(int requestCode, @NonNull String[] permissions, @NonNull int[] grantResults) {
    switch (requestCode) {
        case 0:
            if (grantResults[0] == PackageManager.PERMISSION_GRANTED){
                //执行逻辑代码
                sentMessage();
            }else {
                //没有拿到授权后的处理代码
            }

            break;
    }
}
</code></pre><h2 id="四、Fragment种的动态申请权限"><a href="#四、Fragment种的动态申请权限" class="headerlink" title="四、Fragment种的动态申请权限"></a>四、Fragment种的动态申请权限</h2><p>和Activity的动态申请大体相似，只是第4和第5步有所不同，在Fragment中申请权限，不要使用ActivityCompat.requestPermissions，直接使用Fragment的requestPermissions方法就行，否则会回调到Activity的onRequestPermissionsResult方法。</p>
<p>在Fragment中嵌套Fragment，在子Fragment中使用requestPermissions方法，不会回调父Fragment的onRequestPermissionsResult。不过建议使用getParentFragment().requestPermissions方法，把回调回传给父Fragment的onRequestPermissionsResult方法。</p>
<pre><code>@Override
 public void onRequestPermissionsResult(int requestCode, String[] permissions, int[] grantResults) {
     super.onRequestPermissionsResult(requestCode, permissions, grantResults);
     List&lt;Fragment&gt; fragments = getChildFragmentManager().getFragments();
     if (fragments != null) {
         for (Fragment fragment : fragments) {
             if (fragment != null) {
                 fragment.onRequestPermissionsResult(requestCode,permissions,grantResults);
             }
         }
     }
 }
</code></pre><p>这样就可以在父Fragment中把请求结果透传到子Fragment中</p>

      
    </div>

    

    
    
    

    

    

    

    <footer class="post-footer">
      
        <div class="post-tags">
          
            <a href="/tags/Android/" rel="tag"># Android</a>
          
            <a href="/tags/权限/" rel="tag"># 权限</a>
          
        </div>
      

      
      
      

      
        <div class="post-nav">
          <div class="post-nav-next post-nav-item">
            
              <a href="/2017/05/07/RSS阅读神器——Inoreader/" rel="next" title="RSS阅读神器 —— Inoreader">
                <i class="fa fa-chevron-left"></i> RSS阅读神器 —— Inoreader
              </a>
            
          </div>

          <span class="post-nav-divider"></span>

          <div class="post-nav-prev post-nav-item">
            
              <a href="/2017/07/28/ListView的优化/" rel="prev" title="ListView的优化">
                ListView的优化 <i class="fa fa-chevron-right"></i>
              </a>
            
          </div>
        </div>
      

      
      
    </footer>
  </div>
  
  
  
  </article>



    <div class="post-spread">
      
    </div>
  </div>


          </div>
          

  



        </div>
        
          
  
  <div class="sidebar-toggle">
    <div class="sidebar-toggle-line-wrap">
      <span class="sidebar-toggle-line sidebar-toggle-line-first"></span>
      <span class="sidebar-toggle-line sidebar-toggle-line-middle"></span>
      <span class="sidebar-toggle-line sidebar-toggle-line-last"></span>
    </div>
  </div>

  <aside id="sidebar" class="sidebar">
    
    <div class="sidebar-inner">

      

      
        <ul class="sidebar-nav motion-element">
          <li class="sidebar-nav-toc sidebar-nav-active" data-target="post-toc-wrap">
            文章目录
          </li>
          <li class="sidebar-nav-overview" data-target="site-overview-wrap">
            站点概览
          </li>
        </ul>
      

      <section class="site-overview-wrap sidebar-panel">
        <div class="site-overview">
          <div class="site-author motion-element" itemprop="author" itemscope itemtype="http://schema.org/Person">
            
              <p class="site-author-name" itemprop="name">Bison Qin</p>
              <p class="site-description motion-element" itemprop="description"></p>
          </div>

          
            <nav class="site-state motion-element">
              
                <div class="site-state-item site-state-posts">
                
                  <a href="/archives/">
                
                    <span class="site-state-item-count">13</span>
                    <span class="site-state-item-name">日志</span>
                  </a>
                </div>
              

              
                
                
                <div class="site-state-item site-state-categories">
                  <a href="/categories/index.html">
                    
                    
                      
                    
                      
                    
                      
                    
                      
                    
                    <span class="site-state-item-count">4</span>
                    <span class="site-state-item-name">分类</span>
                  </a>
                </div>
              

              
                
                
                <div class="site-state-item site-state-tags">
                  <a href="/tags/index.html">
                    
                    
                      
                    
                      
                    
                      
                    
                      
                    
                      
                    
                      
                    
                      
                    
                      
                    
                    <span class="site-state-item-count">8</span>
                    <span class="site-state-item-name">标签</span>
                  </a>
                </div>
              
            </nav>
          

          

          

          
          

          
          

          
            
          
          

        </div>
      </section>

      
      <!--noindex-->
        <section class="post-toc-wrap motion-element sidebar-panel sidebar-panel-active">
          <div class="post-toc">

            
              
            

            
              <div class="post-toc-content"><ol class="nav"><li class="nav-item nav-level-2"><a class="nav-link" href="#一、Android-6-0后的权限问题"><span class="nav-number">1.</span> <span class="nav-text">一、Android 6.0后的权限问题</span></a></li><li class="nav-item nav-level-2"><a class="nav-link" href="#二、权限的分类"><span class="nav-number">2.</span> <span class="nav-text">二、权限的分类</span></a><ol class="nav-child"><li class="nav-item nav-level-3"><a class="nav-link" href="#1-Normal-permissions"><span class="nav-number">2.1.</span> <span class="nav-text">1. Normal permissions</span></a></li><li class="nav-item nav-level-3"><a class="nav-link" href="#2-Dangerous-permissions"><span class="nav-number">2.2.</span> <span class="nav-text">2. Dangerous permissions</span></a></li><li class="nav-item nav-level-3"><a class="nav-link" href="#3-Special-Permissions"><span class="nav-number">2.3.</span> <span class="nav-text">3.Special Permissions</span></a></li></ol></li><li class="nav-item nav-level-2"><a class="nav-link" href="#三、动态申请权限"><span class="nav-number">3.</span> <span class="nav-text">三、动态申请权限</span></a><ol class="nav-child"><li class="nav-item nav-level-3"><a class="nav-link" href="#1-配置权限"><span class="nav-number">3.1.</span> <span class="nav-text">1. 配置权限</span></a></li><li class="nav-item nav-level-3"><a class="nav-link" href="#2-判断系统版本"><span class="nav-number">3.2.</span> <span class="nav-text">2.判断系统版本</span></a></li><li class="nav-item nav-level-3"><a class="nav-link" href="#3-判断是否申请了权限"><span class="nav-number">3.3.</span> <span class="nav-text">3.判断是否申请了权限</span></a></li><li class="nav-item nav-level-3"><a class="nav-link" href="#4-判断是否可以通过弹窗解释授权"><span class="nav-number">3.4.</span> <span class="nav-text">4.判断是否可以通过弹窗解释授权</span></a></li><li class="nav-item nav-level-3"><a class="nav-link" href="#5-申请权限"><span class="nav-number">3.5.</span> <span class="nav-text">5.申请权限</span></a></li><li class="nav-item nav-level-3"><a class="nav-link" href="#6-对申请权限结果进行处理"><span class="nav-number">3.6.</span> <span class="nav-text">6.对申请权限结果进行处理</span></a></li></ol></li><li class="nav-item nav-level-2"><a class="nav-link" href="#四、Fragment种的动态申请权限"><span class="nav-number">4.</span> <span class="nav-text">四、Fragment种的动态申请权限</span></a></li></ol></div>
            

          </div>
        </section>
      <!--/noindex-->
      

      

    </div>
  </aside>


        
      </div>
    </main>

    <footer id="footer" class="footer">
      <div class="footer-inner">
        <div class="copyright">&copy; <span itemprop="copyrightYear">2018</span>
  <span class="with-love" id="animate">
    <i class="fa fa-user"></i>
  </span>
  <span class="author" itemprop="copyrightHolder">Bison Qin</span>

  

  
</div>




  <div class="powered-by">由 <a class="theme-link" target="_blank" href="https://hexo.io">Hexo</a> 强力驱动 v3.7.1</div>



  <span class="post-meta-divider">|</span>



  <div class="theme-info">主题 &mdash; <a class="theme-link" target="_blank" href="https://github.com/theme-next/hexo-theme-next">NexT.Pisces</a> v6.2.0</div>




        








        
      </div>
    </footer>

    
      <div class="back-to-top">
        <i class="fa fa-arrow-up"></i>
        
      </div>
    

    

  </div>

  

<script type="text/javascript">
  if (Object.prototype.toString.call(window.Promise) !== '[object Function]') {
    window.Promise = null;
  }
</script>


























  
  
    <script type="text/javascript" src="/lib/jquery/index.js?v=2.1.3"></script>
  

  
  
    <script type="text/javascript" src="/lib/velocity/velocity.min.js?v=1.2.1"></script>
  

  
  
    <script type="text/javascript" src="/lib/velocity/velocity.ui.min.js?v=1.2.1"></script>
  


  


  <script type="text/javascript" src="/js/src/utils.js?v=6.2.0"></script>

  <script type="text/javascript" src="/js/src/motion.js?v=6.2.0"></script>



  
  


  <script type="text/javascript" src="/js/src/affix.js?v=6.2.0"></script>

  <script type="text/javascript" src="/js/src/schemes/pisces.js?v=6.2.0"></script>



  
  <script type="text/javascript" src="/js/src/scrollspy.js?v=6.2.0"></script>
<script type="text/javascript" src="/js/src/post-details.js?v=6.2.0"></script>



  


  <script type="text/javascript" src="/js/src/bootstrap.js?v=6.2.0"></script>



  



	





  





  










  





  

  
  <script src="https://cdn1.lncld.net/static/js/av-core-mini-0.6.4.js"></script>
  <script>AV.initialize("M90nbI9KgVkqdeNl4kIE1aY4-gzGzoHsz", "3I8HRy0nT1nMlMw7enfvrnu5");</script>
  <script>
    function showTime(Counter) {
      var query = new AV.Query(Counter);
      var entries = [];
      var $visitors = $(".leancloud_visitors");

      $visitors.each(function () {
        entries.push( $(this).attr("id").trim() );
      });

      query.containedIn('url', entries);
      query.find()
        .done(function (results) {
          var COUNT_CONTAINER_REF = '.leancloud-visitors-count';

          if (results.length === 0) {
            $visitors.find(COUNT_CONTAINER_REF).text(0);
            return;
          }

          for (var i = 0; i < results.length; i++) {
            var item = results[i];
            var url = item.get('url');
            var time = item.get('time');
            var element = document.getElementById(url);

            $(element).find(COUNT_CONTAINER_REF).text(time);
          }
          for(var i = 0; i < entries.length; i++) {
            var url = entries[i];
            var element = document.getElementById(url);
            var countSpan = $(element).find(COUNT_CONTAINER_REF);
            if( countSpan.text() == '') {
              countSpan.text(0);
            }
          }
        })
        .fail(function (object, error) {
          console.log("Error: " + error.code + " " + error.message);
        });
    }

    function addCount(Counter) {
      var $visitors = $(".leancloud_visitors");
      var url = $visitors.attr('id').trim();
      var title = $visitors.attr('data-flag-title').trim();
      var query = new AV.Query(Counter);

      query.equalTo("url", url);
      query.find({
        success: function(results) {
          if (results.length > 0) {
            var counter = results[0];
            counter.fetchWhenSave(true);
            counter.increment("time");
            
              var $element = $(document.getElementById(url));
              $element.find('.leancloud-visitors-count').text(counter.get('time'));
            
            counter.save(null, {
              success: function(counter) {
                
              },
              error: function(counter, error) {
                console.log('Failed to save Visitor num, with error message: ' + error.message);
              }
            });
          } else {
            
              var $element = $(document.getElementById(url));
              $element.find('.leancloud-visitors-count').text('Counter not initialized! See more at console err msg.');
              console.error('ATTENTION! LeanCloud counter has security bug, see here how to solve it: https://github.com/theme-next/hexo-leancloud-counter-security. \n But you also can use LeanCloud without security, by set \'security\' option to \'false\'.');
            
          }
        },
        error: function(error) {
          console.log('Error:' + error.code + " " + error.message);
        }
      });
    }

    $(function() {
      var Counter = AV.Object.extend("Counter");
      if ($('.leancloud_visitors').length == 1) {
        addCount(Counter);
      } else if ($('.post-title-link').length > 1) {
        showTime(Counter);
      }
    });
  </script>



  

  

  

  
  

  

  

  

  

  

</body>
</html>
